package com.ketty;

import com.google.common.collect.Maps;
import com.ketty.entiy.User;
import org.apache.ibatis.annotations.Select;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 1.引入JDBC驱动包
 * 2.引入MyBatis包
 * <p>
 * MyBatis的架构设计
 * 1.配置文件
 * 2.Mapper仓库
 * 接口如何实例化一个Bean？
 * 使用 代理模式 去实现    JDK的动态代理
 * 拦截一个方法的执行，执行 invoke()
 */
interface UserMapper {
    @Select("select * from user where id=#{id}")
    List<User> selectUserList(Integer id, String name);
}

public class Application {
    public static void main(String[] args) {
        /**
         * 1.接口如何实例化?
         *   通过代理类的代理实例对象，参数：类的加载器，类模板的数组集合，InvocationHandler
         *
         */
        UserMapper userMapper = (UserMapper) Proxy.newProxyInstance(Application.class.getClassLoader(), new Class<?>[]{UserMapper.class}, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 获取方法名
                System.out.println(method.getName());
                // 获取注解上的sql语句
                Select annotation = method.getAnnotation(Select.class);
                System.out.println(annotation);
                // 打印传输的参数信息
                System.out.println(Arrays.toString(args));
                Map<String, Object> nameArgMap = buildMethodArgNameMap(method, args);
                return null;
            }
        });
        userMapper.selectUserList(1, "test");
    }

    //    解析sql语句
    public static String parseSQL(String sql, Map<String, Object> nameArgMap) {

        String parseSQL = "";
        StringBuilder stringBuilder=new StringBuilder();
        int length = sql.length();
        for (int i = 0; i < length; i++) {
            char c = sql.charAt(i);
            if (c=='#'){
                int nextIndex = i+ 1;
                char nextChar = sql.charAt(nextIndex);
                if (nextChar!='{'){
                    throw new RuntimeException(String.format("这里应该为#{\nsql:%s\nindex:%d",
                            stringBuilder.toString(),nextIndex));
                }
                StringBuilder argsSB=new StringBuilder();
                i = parseSQArg(argsSB, sql, nextIndex);
                String argsName = argsSB.toString();
                Object argValue = nameArgMap.get(argsName);
                stringBuilder.append(argValue.toString());
                continue;
            }
            stringBuilder.append(c);
        }

        return parseSQL;
    }

    private static int parseSQArg(StringBuilder argsSB, String sql, int nextIndex) {
        nextIndex++;
        for (; nextIndex < sql.length(); nextIndex++) {

        }
        return 0;
    }

    /**
     * @param method
     * @param args
     * @return
     */
    private static Map<String, Object> buildMethodArgNameMap(Method method, Object[] args) {
        Map<String, Object> nameArgMap = Maps.newConcurrentMap();
        Parameter[] parameters = method.getParameters();
        if (parameters.length != args.length) {
            throw new RuntimeException();
        }
        int index[] = {0};
        //  适合并发小的业务场景
//       Arrays.asList(parameters).forEach(parameter -> {
        Arrays.asList(parameters).parallelStream().forEach(parameter -> {
            String name = parameter.getName();
            nameArgMap.put(name, args[index[0]]);
            index[0]++;
        });
        return nameArgMap;
    }

    /**
     * 动态代理？
     *
     */
}
